home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / 3dshade.exe / 3DSHADE.C < prev    next >
C/C++ Source or Header  |  1991-07-22  |  23KB  |  575 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <malloc.h>
  4. #include <graph.h>
  5. #include <process.h>
  6. #include <stdlib.h>
  7. #include <conio.h>
  8.  
  9. #define TRUE -1
  10. #define FALSE 0
  11.  
  12. static double f(double,double);
  13.        void   main(void);
  14.  
  15. void main()
  16.   {
  17.     static double aspect_ratio;
  18.     static double box_delta_x;
  19.     static double box_delta_y;
  20.     static int    box_num_1;
  21.     static int    box_num_2;
  22.     static int    box_x [4];
  23.     static double box_x_intercept;
  24.     static int    box_x1;
  25.     static int    box_x2;
  26.     static int    box_y [4];
  27.     static int    box_y_max;
  28.     static int    box_y_min;
  29.     static double box_y_offset;
  30.     static int    box_y1;
  31.     static short  color;
  32.     static double cos_rotation;
  33.     static double cos_tilt;
  34.     static double delta_x;
  35.     static double delta_y;
  36.     static double delta_z;
  37.     static int    finished;
  38.     static int    intercept_count_mod_2;
  39.     static int    key_index_1;
  40.     static int    key_index_2;
  41.     static int    line_x1;
  42.     static int    line_x2;
  43.     static int    line_y1;
  44.     static int    line_y2;
  45.     static double magnitude_normal;
  46.     static int    max_y_out;
  47.     static int    max_z_out;
  48.     static double normal_x;
  49.     static double normal_y;
  50.     static double normal_z;
  51.     static double num_bytes;
  52.     static int    num_x_divisions;
  53.     static int    num_x_primes;
  54.     static int    num_y_divisions;
  55.     static double pixels_per_unit;
  56.     static int    prime_num;
  57.     static double radians;
  58.     static double radians_per_degree;
  59.     static int    response;
  60.     static double rotation;
  61.     static double sin_rotation;
  62.     static double sin_tilt;
  63.     static int    sort_left;
  64.     static int    sort_right;
  65.     static double sort_t1;
  66.     static int    sort_t2;
  67.     static int    sort_t3;
  68.     static double tilt;
  69.     static long   tint;
  70.     static long   tint_increment;
  71.     static double x;
  72.     static int    *x_division_index;
  73.     static int    x_division_num;
  74.     static double x_eye;
  75.     static double x_max;
  76.     static double x_min;
  77.     static double *x_prime;
  78.     static double *x_prime_sorted;
  79.     static double x_prime_max;
  80.     static int    x_prime_num;
  81.     static double x_rotated;
  82.     static double x0;
  83.     static double x1;
  84.     static double x2;
  85.     static double x3;
  86.     static double y;
  87.     static double y_center;
  88.     static int    *y_division_index;
  89.     static int    y_division_num;
  90.     static double y_max;
  91.     static double y_min;
  92.     static double y_offset;
  93.     static double y_out_max;
  94.     static double *y_prime;
  95.     static double y_prime_max;
  96.     static double y_prime_min;
  97.     static double y0;
  98.     static double y1;
  99.     static double y2;
  100.     static double y3;
  101.     static double z;
  102.     static double z_center;
  103.     static double z_offset;
  104.     static double z_out_max;
  105.     static double *z_prime;
  106.     static double z_prime_max;
  107.     static double z_prime_min;
  108.     static double z0;
  109.     static double z1;
  110.     static double z2;
  111.     static double z3;
  112.  
  113.     max_y_out=319;
  114.     max_z_out=199;
  115.     printf("                             Three Dimensional Plot\n\n\n\n");
  116.     printf("Smallest value for x?  "); fflush(stdout);
  117.     scanf("%lf",&x_min);
  118.     printf("Largest value for x?  "); fflush(stdout);
  119.     scanf("%lf",&x_max);
  120.     printf("Smallest value for y?  "); fflush(stdout);
  121.     scanf("%lf",&y_min);
  122.     printf("Largest value for y?  "); fflush(stdout);
  123.     scanf("%lf",&y_max);
  124.     do
  125.       {
  126.         do
  127.           {
  128.             printf("Number of divisions for x?  "); fflush(stdout);
  129.             scanf("%d",&num_x_divisions);
  130.             if (num_x_divisions <= 1)
  131.               printf("? there must be at least 2 divisions\n");
  132.           }
  133.         while (num_x_divisions <= 1);
  134.         do
  135.           {
  136.             printf("Number of divisions for y?  "); fflush(stdout);
  137.             scanf("%d",&num_y_divisions);
  138.             if (num_y_divisions <= 1)
  139.               printf("? there must be at least 2 divisions\n");
  140.           }
  141.         while (num_y_divisions <= 1);
  142.         num_bytes=(float) num_x_divisions;
  143.         num_bytes*=((float) num_y_divisions);
  144.         num_bytes*=((float) sizeof(double));
  145.         if (num_bytes > 65536.0)
  146.           printf("? too many cells\n"); /* Oh, for a 32 bit compiler! */
  147.       }
  148.     while (num_bytes > 65536.0);
  149.     if ((x_prime
  150.      =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
  151.      == NULL)
  152.       {
  153.         printf("Fatal error:  out of memory\n");
  154.         exit(4);
  155.       }
  156.     if ((x_prime_sorted
  157.      =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
  158.      == NULL)
  159.       {
  160.         printf("Fatal error:  out of memory\n");
  161.         exit(4);
  162.       }
  163.     if ((y_prime
  164.      =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
  165.      == NULL)
  166.       {
  167.         printf("Fatal error:  out of memory\n");
  168.         exit(4);
  169.       }
  170.     if ((z_prime
  171.      =(double *) malloc(num_x_divisions*num_y_divisions*sizeof(double)))
  172.      == NULL)
  173.       {
  174.         printf("Fatal error:  out of memory\n");
  175.         exit(4);
  176.       }
  177.     if ((x_division_index
  178.      =(int *) malloc(num_x_divisions*num_y_divisions*sizeof(int)))
  179.      == NULL)
  180.       {
  181.         printf("Fatal error:  out of memory\n");
  182.         exit(4);
  183.       }
  184.     if ((y_division_index
  185.      =(int *) malloc(num_x_divisions*num_y_divisions*sizeof(int)))
  186.      == NULL)
  187.       {
  188.         printf("Fatal error:  out of memory\n");
  189.         exit(4);
  190.       }
  191.     do
  192.       {
  193.         printf("Rotation about the z-axis (degrees)?  "); fflush(stdout);
  194.         scanf("%lf",&rotation);
  195.         printf("Tilt about the resulting y-axis (degrees)?  "); fflush(stdout);
  196.         scanf("%lf",&tilt);
  197.         printf("After the plot is displayed, press a key to continue.\n");
  198.         printf("Evaluating function...\n");
  199.         radians_per_degree=atan(1.0)/45.0;
  200.         radians=tilt*radians_per_degree;
  201.         cos_tilt=cos(radians);
  202.         sin_tilt=sin(radians);
  203.         radians=rotation*radians_per_degree;
  204.         cos_rotation=cos(radians);
  205.         sin_rotation=sin(radians);
  206.         z=f(x_min,y_min);
  207.         x_rotated=x_min*cos_rotation+y_min*sin_rotation;
  208.         y_prime_min=-x_min*sin_rotation+y_min*cos_rotation;
  209.         z_prime_min=-x_rotated*sin_tilt+z*cos_tilt;
  210.         y_prime_max=y_prime_min;
  211.         z_prime_max=z_prime_min;
  212.         x_prime_max=x_rotated*cos_tilt+z*sin_tilt;
  213.         delta_x=(double) num_x_divisions;
  214.         delta_x=(x_max-x_min)/delta_x;
  215.         delta_y=(double) num_y_divisions;
  216.         delta_y=(y_max-y_min)/delta_y;
  217.         x=x_min;
  218.         num_x_primes=0;
  219.         for (x_division_num=0; x_division_num < num_x_divisions;
  220.          x_division_num++)
  221.           {
  222.             y=y_min;
  223.             for (y_division_num=0; y_division_num < num_y_divisions;
  224.              y_division_num++)
  225.               {
  226.                 z=f(x,y);
  227.                 x_division_index[num_x_primes]=x_division_num;
  228.                 y_division_index[num_x_primes]=y_division_num;
  229.                 x_rotated=x*cos_rotation+y*sin_rotation;
  230.                 y_prime[num_x_primes]=-x*sin_rotation+y*cos_rotation;
  231.                 x_prime[num_x_primes]=x_rotated*cos_tilt+z*sin_tilt;
  232.                 z_prime[num_x_primes]=-x_rotated*sin_tilt+z*cos_tilt;
  233.                 if (x_prime[num_x_primes] > x_prime_max)
  234.                   x_prime_max=x_prime[num_x_primes];
  235.                 if (y_prime[num_x_primes] < y_prime_min)
  236.                   y_prime_min=y_prime[num_x_primes];
  237.                 if (y_prime[num_x_primes] > y_prime_max) 
  238.                   y_prime_max=y_prime[num_x_primes];
  239.                 if (z_prime[num_x_primes] < z_prime_min)
  240.                   z_prime_min=z_prime[num_x_primes];
  241.                 if (z_prime[num_x_primes] > z_prime_max)
  242.                   z_prime_max=z_prime[num_x_primes];
  243.                 y+=delta_y;
  244.                 num_x_primes++;
  245.               } 
  246.             x+=delta_x;
  247.           }
  248.         printf("Adjusting perspective...\n");
  249.         if ((y_prime_max-y_prime_min) > (z_prime_max-z_prime_min))
  250.           x_eye=2.0